package cn.iocoder.yudao.module.iot.controller.admin.device;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理端 - IoT 设备管理")
@RestController
@RequestMapping("/iot/device/admin")
@Slf4j
public class IotAdminDeviceController {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @GetMapping("/user-device-services")
    @Operation(summary = "管理员获取用户设备选择的服务")
    @Parameter(name = "userId", description = "用户ID", required = true, example = "1024")
    @Parameter(name = "deviceId", description = "设备ID", required = false, example = "1024")
    @TenantIgnore
    public CommonResult<List<Map<String, Object>>> getAdminUserDeviceServices(@RequestParam("userId") Long userId, 
                                                               @RequestParam(value = "deviceId", required = false) Long deviceId) {
        log.info("[IotAdminDeviceController] 管理员获取用户设备服务请求，用户ID: {}, 设备ID: {}", userId, deviceId);

        try {
            List<Map<String, Object>> services = new ArrayList<>();
            
            if (deviceId != null) {
                // 获取指定设备的服务
                String redisKey = String.format("iot:user:device:services:%d:%d", userId, deviceId);
                String cachedServices = redisTemplate.opsForValue().get(redisKey);
                
                if (cachedServices != null) {
                    try {
                        // 尝试解析为完整的服务信息
                        @SuppressWarnings("unchecked")
                        List<Object> rawServices = JsonUtils.parseArray(cachedServices, Object.class);
                        List<Map<String, Object>> cachedServicesList = new ArrayList<>();
                        
                        // 手动转换类型
                        for (Object rawService : rawServices) {
                            if (rawService instanceof Map) {
                                @SuppressWarnings("unchecked")
                                Map<String, Object> service = (Map<String, Object>) rawService;
                                cachedServicesList.add(service);
                            }
                        }
                        
                        // 检查是否包含service_name字段，如果没有则说明是旧格式缓存
                        if (!cachedServicesList.isEmpty() && cachedServicesList.get(0).containsKey("service_name")) {
                            services = cachedServicesList;
                            log.info("[getAdminUserDeviceServices] 从Redis缓存获取服务成功，用户ID: {}, 设备ID: {}, 服务: {}", 
                                userId, deviceId, services);
                        } else {
                            // 旧格式缓存，删除并重新获取
                            log.info("[getAdminUserDeviceServices] 检测到旧格式缓存，删除并重新获取，用户ID: {}, 设备ID: {}", userId, deviceId);
                            redisTemplate.delete(redisKey);
                        }
                    } catch (Exception e) {
                        // 解析失败，可能是旧格式，删除缓存
                        log.info("[getAdminUserDeviceServices] 缓存解析失败，删除缓存并重新获取，用户ID: {}, 设备ID: {}", userId, deviceId);
                        redisTemplate.delete(redisKey);
                    }
                }
                
                // 如果缓存被删除或不存在，从数据库获取
                if (services.isEmpty()) {
                    String sql = "SELECT service_identifier, service_name, description FROM iot_user_device_services WHERE user_id = ? AND device_id = ? AND deleted = 0 ORDER BY create_time";
                    services = jdbcTemplate.queryForList(sql, userId, deviceId);
                    
                    // 如果没有service_name，则生成默认值
                    for (Map<String, Object> service : services) {
                        if (service.get("service_name") == null || ((String) service.get("service_name")).trim().isEmpty()) {
                            String identifier = (String) service.get("service_identifier");
                            service.put("service_name", getServiceDisplayName(identifier));
                        }
                        if (service.get("description") == null || ((String) service.get("description")).trim().isEmpty()) {
                            String identifier = (String) service.get("service_identifier");
                            service.put("description", getServiceDescription(identifier));
                        }
                    }
                    
                    // 更新Redis缓存（缓存完整的服务信息）
                    if (!services.isEmpty()) {
                        redisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(services), 24, TimeUnit.HOURS);
                        log.info("[getAdminUserDeviceServices] Redis缓存更新成功，用户ID: {}, 设备ID: {}, 服务: {}", 
                            userId, deviceId, services);
                    }
                }
            } else {
                // 获取用户所有设备的服务
                String sql = "SELECT DISTINCT service_identifier, service_name, description FROM iot_user_device_services WHERE user_id = ? AND deleted = 0 ORDER BY service_identifier";
                services = jdbcTemplate.queryForList(sql, userId);
                
                // 如果没有service_name，则生成默认值
                for (Map<String, Object> service : services) {
                    if (service.get("service_name") == null || ((String) service.get("service_name")).trim().isEmpty()) {
                        String identifier = (String) service.get("service_identifier");
                        service.put("service_name", getServiceDisplayName(identifier));
                    }
                    if (service.get("description") == null || ((String) service.get("description")).trim().isEmpty()) {
                        String identifier = (String) service.get("service_identifier");
                        service.put("description", getServiceDescription(identifier));
                    }
                }
            }
            
            log.info("[getAdminUserDeviceServices] 获取用户设备服务成功，用户ID: {}, 设备ID: {}, 服务数量: {}", 
                userId, deviceId, services.size());
            return success(services);
            
        } catch (Exception e) {
            log.error("[getAdminUserDeviceServices] 获取用户设备服务异常，用户ID: {}, 设备ID: {}", userId, deviceId, e);
            return CommonResult.error(500, "获取服务失败：" + e.getMessage());
        }
    }

    /**
     * 根据服务标识符获取服务显示名称
     */
    private String getServiceDisplayName(String identifier) {
        if (identifier == null) {
            return "未知服务";
        }
        
        switch (identifier) {
            case "control":
                return "控制服务";
            case "control1":
                return "控制1服务";
            case "remote":
                return "红外遥控";
            case "alarm":
                return "告警";
            case "led":
                return "测试灯";
            default:
                return identifier;
        }
    }

    /**
     * 根据服务标识符获取服务描述
     */
    private String getServiceDescription(String identifier) {
        if (identifier == null) {
            return "无描述";
        }
        
        switch (identifier) {
            case "control":
                return "设备控制服务，用于开关控制";
            case "control1":
                return "设备控制1服务，用于开关控制";
            case "remote":
                return "红外遥控服务，用于远程控制";
            case "alarm":
                return "告警服务，用于设备告警";
            case "led":
                return "测试灯服务，用于灯光控制";
            default:
                return "无描述";
        }
    }
} 